home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 4 / ETO Development Tools 4.iso / Tools - Objects / MacApp / MacApp 3.0a2 / Libraries / UDocument.cp < prev    next >
Encoding:
Text File  |  1991-05-01  |  24.5 KB  |  896 lines  |  [TEXT/MPS ]

  1. // UDocument.cp 
  2. // Copyright © 1984-1991 by Apple Computer Inc.    All rights reserved.
  3.  
  4. #ifndef __TOOLUTILS__
  5. #include <ToolUtils.h>
  6. #endif
  7.  
  8. #ifndef __PACKAGES__
  9. #include <Packages.h>
  10. #endif
  11.  
  12. #ifndef __UDESIGNATOR__
  13. #include <UDesignator.h>
  14. #endif
  15.  
  16. #ifndef __UAPPLICATION__
  17. #include <UApplication.h>
  18. #endif
  19.  
  20. #ifndef __UCLIPBOARDMGR__
  21. #include <UClipboardMgr.h>
  22. #endif
  23.  
  24. #ifndef __UPRINTHANDLER__
  25. #include <UPrintHandler.h>
  26. #endif
  27.  
  28. #ifndef __UWINDOW__
  29. #include <UWindow.h>
  30. #endif
  31.  
  32. #ifndef __UMACAPPUTILITIES__
  33. #include <UMacAppUtilities.h>
  34. #endif
  35.  
  36. #ifndef __UERRORMGR__
  37. #include <UErrorMgr.h>
  38. #endif
  39.  
  40. #ifndef __UMENUMGR__
  41. #include <UMenuMgr.h>
  42. #endif
  43.  
  44. #ifndef __UMACAPPGLOBALS__
  45. #include <UMacAppGlobals.h>
  46. #endif
  47.  
  48. #ifndef __USTREAM__
  49. #include <UStream.h>
  50. #endif
  51.  
  52. #ifndef __UVIEWSERVER__
  53. #include <UViewServer.h>
  54. #endif
  55.  
  56. #ifndef __UDOCUMENT__
  57. #include <UDocument.h>
  58. #endif
  59.  
  60. //--------------------------------------------------------------------------------------------------
  61. short gNumUntitled = 1;                                // call the first document "Untitled-1"
  62.  
  63. //--------------------------------------------------------------------------------------------------
  64. #pragma segment MAViewRes
  65.  
  66. CWindowIterator::CWindowIterator(TDocument* itsDocument,
  67.                            ArrayIndex itsLowBound,
  68.                            ArrayIndex itsHighBound,
  69.                            Boolean itsForward) :
  70.     CObjectIterator(itsDocument ? itsDocument->fWindowList : NULL, itsLowBound, itsHighBound, itsForward)
  71. {
  72. }
  73.  
  74. //--------------------------------------------------------------------------------------------------
  75. #pragma segment MADocumentRes
  76.  
  77. CWindowIterator::CWindowIterator(TDocument* itsDocument,
  78.                            Boolean itsForward) :
  79.     CObjectIterator(itsDocument ? itsDocument->fWindowList : NULL, itsForward)
  80. {
  81. }
  82.  
  83. //--------------------------------------------------------------------------------------------------
  84. #pragma segment MADocumentRes
  85.  
  86. CWindowIterator::CWindowIterator(TDocument* itsDocument) :
  87.     CObjectIterator(itsDocument ? itsDocument->fWindowList : NULL)
  88. {
  89. }
  90.  
  91. //--------------------------------------------------------------------------------------------------
  92. #pragma segment MADocumentRes
  93.  
  94. TWindow* CWindowIterator::CurrentWindow(void)
  95. {
  96.     return (TWindow *)this->CurrentObject();
  97. }
  98.  
  99. //--------------------------------------------------------------------------------------------------
  100. #pragma segment MADocumentRes
  101.  
  102. TWindow* CWindowIterator::FirstWindow(void)
  103. {
  104.     return (TWindow*)this->FirstObject();
  105. }
  106.  
  107. //--------------------------------------------------------------------------------------------------
  108. #pragma segment MAViewRes
  109.  
  110. TWindow* CWindowIterator::NextWindow(void)
  111. {
  112.     return (TWindow*)this->NextObject();
  113. }
  114.  
  115. //--------------------------------------------------------------------------------------------------
  116. #pragma segment MAWriteFile
  117.  
  118. pascal void TSaveDocCommand::DoIt(void)
  119. {
  120.     fChangedDocument->SaveDocument(fID);
  121. }
  122.  
  123. //--------------------------------------------------------------------------------------------------
  124. #pragma segment MASelCommand
  125. pascal void TSaveDocCommand::Initialize(void)    // override 
  126. {
  127.     inherited::Initialize();
  128.     fChangedDocument = NULL;
  129. }
  130.  
  131. //--------------------------------------------------------------------------------------------------
  132. #pragma segment MASelCommand
  133.  
  134. pascal void TSaveDocCommand::ISaveDocCommand(CmdNumber itsCmdNumber,
  135.                                              TDocument* itsDocument)
  136. {
  137.     this->INoChangesCommand(itsCmdNumber, itsDocument, NULL);
  138.     fChangedDocument = itsDocument;
  139. }
  140.  
  141. //--------------------------------------------------------------------------------------------------
  142. #pragma segment MAFields
  143.  
  144. pascal void TSaveDocCommand::Fields(TObject* obj)// override 
  145. {
  146.     obj->DoToField("TSaveDocCommand", (Ptr)NULL, bClass);
  147.     inherited::Fields(obj);
  148. }
  149.  
  150. //--------------------------------------------------------------------------------------------------
  151. #pragma segment MAReadFile
  152.  
  153. pascal void TRevertDocCommand::DoIt(void)
  154. {
  155.     Str255 name;
  156.     FailInfo fi;
  157.  
  158.     fChangedDocument->GetTitle(name);
  159.     ParamText(name, "", "", "");
  160.     //!!! This should be programatically defeatable
  161.     if (MacAppAlert(phRevert, NULL) == kYesButton)
  162.     {
  163.         if (fi.Try())
  164.         {
  165.             fChangedDocument->RevertDocument();
  166.             fi.Success();
  167.         }
  168.         else    // Recover
  169.         {
  170.             fChangedDocument->ShowReverted();    // make sure screen is updated 
  171.             fi.ReSignal();
  172.         }
  173.         fChangedDocument->ShowReverted();
  174.     }
  175. }
  176.  
  177. //--------------------------------------------------------------------------------------------------
  178. #pragma segment MASelCommand
  179. pascal void TRevertDocCommand::Initialize(void)    // override 
  180. {
  181.     inherited::Initialize();
  182.     fChangedDocument = NULL;
  183. }
  184.  
  185. //--------------------------------------------------------------------------------------------------
  186. #pragma segment MASelCommand
  187.  
  188. pascal void TRevertDocCommand::IRevertDocCommand(CmdNumber itsCmdNumber,
  189.                                                  TDocument* itsDocument)
  190. {
  191.     this->INoChangesCommand(itsCmdNumber, itsDocument, NULL);
  192.     fChangedDocument = itsDocument;
  193. }
  194.  
  195. //--------------------------------------------------------------------------------------------------
  196. #pragma segment MAFields
  197.  
  198. pascal void TRevertDocCommand::Fields(TObject* obj)// override 
  199. {
  200.     obj->DoToField("TRevertDocCommand", (Ptr)NULL, bClass);
  201.  
  202.     inherited::Fields(obj);
  203. }
  204.  
  205. //--------------------------------------------------------------------------------------------------
  206. #pragma segment MAOpen
  207. pascal void TDocument::Initialize(void)            // override 
  208. {
  209.     inherited::Initialize();
  210.  
  211.     fTitle = "";
  212.     fWindowList = NULL;
  213.     fViewList = NULL;
  214.     fPrintInfo = NULL;
  215.     fSavePrintInfo = TRUE;
  216.     fSharePrintInfo = TRUE;
  217.     fReopenAlert = TRUE;
  218.     fCommitOnSave = TRUE;
  219.     fChangeCount = 0;
  220.     fUserSelection = NULL;
  221. }
  222.  
  223. //--------------------------------------------------------------------------------------------------
  224. #pragma segment MAOpen
  225.  
  226. pascal void TDocument::IDocument(void)
  227. {
  228.     FailInfo fi;
  229.  
  230.     this->IEvtHandler(gApplication);
  231.  
  232.     if (fi.Try())
  233.     {
  234.         fWindowList = NewList();
  235. #if qDebug
  236.         fWindowList->SetEltType("TWindow");
  237. #endif
  238.  
  239.         fViewList = NewList();
  240. #if qDebug
  241.         fViewList->SetEltType("TView");
  242. #endif
  243.  
  244.         fi.Success();
  245.     }
  246.     else    // Recover
  247.     {
  248.         this->Free();
  249.         fi.ReSignal();
  250.     }
  251. }
  252.  
  253. //--------------------------------------------------------------------------------------------------
  254. #pragma segment MAClose
  255.  
  256. pascal void TDocument::Free(void)                // override 
  257.  
  258. {
  259.     gApplication->DeleteDocument(this);
  260.  
  261.     fWindowList = (TList *)FreeListIfObject(fWindowList);
  262.     fViewList = (TList *)FreeListIfObject(fViewList);
  263.  
  264.     if (fSharePrintInfo)
  265.         fPrintInfo = DisposeIfHandle(fPrintInfo);
  266.     else
  267.         fPrintInfo = NULL;                        // Always drop my reference 
  268.  
  269.     fUserSelection = (TDesignator *)FreeIfObject(fUserSelection);
  270.  
  271.     inherited::Free();
  272. }
  273.  
  274. //--------------------------------------------------------------------------------------------------
  275. #pragma segment MAOpen
  276.  
  277. pascal void TDocument::AddView(TView* aView)
  278. {
  279.     // Protect against double installation and keep in synch with window list 
  280.  
  281.     if (fViewList && (fViewList->GetIdentityItemNo(aView) == 0))
  282.         fViewList->Insert(aView);
  283.  
  284.     if (fWindowList && aView && aView->IsMemberClass(GetClassIDFromName("TWindow")))
  285.         if (fWindowList->GetIdentityItemNo(aView) == 0)
  286.             fWindowList->Insert(aView);
  287. }
  288.  
  289. //--------------------------------------------------------------------------------------------------
  290. #pragma segment MAOpen
  291.  
  292. pascal void TDocument::AddWindow(TWindow* aWindow)
  293. {
  294.     // Protect against double installation and keep in synch with window list 
  295.     // doesn't already exist in list
  296.     if (fWindowList && (fWindowList->GetIdentityItemNo(aWindow) == 0))
  297.         fWindowList->Insert(aWindow);
  298.  
  299.     // ??? should we only have one list now… maybe created on demand? (post 2.0) */
  300.     if (fViewList && (fViewList->GetIdentityItemNo(aWindow) == 0))
  301.         fViewList->Insert(aWindow);
  302. }
  303.  
  304. //--------------------------------------------------------------------------------------------------
  305. #pragma segment MARes
  306.  
  307. pascal Boolean TDocument::AlreadyOpen(TFile*)
  308. {
  309.     return FALSE;
  310. }
  311.  
  312. //--------------------------------------------------------------------------------------------------
  313. #pragma segment MAOpen
  314.  
  315. pascal void TDocument::AttachPrintHandler(TPrintHandler* itsPrintHandler)
  316. {
  317.     if (itsPrintHandler)
  318.         itsPrintHandler->fDocument = this;
  319.  
  320.     TPrintMenuBehavior* aPrintMenuBehavior = new TPrintMenuBehavior;
  321.     aPrintMenuBehavior->IPrintMenuBehavior(itsPrintHandler);
  322.     this->AddBehavior(aPrintMenuBehavior);
  323.     if (!fPrintInfo && fSharePrintInfo)
  324.         fPrintInfo = itsPrintHandler->GetPrintInfo();
  325. }
  326.  
  327. //--------------------------------------------------------------------------------------------------
  328. #pragma segment MAOpen
  329.  
  330. pascal void TDocument::DetachPrintHandler(TPrintHandler* itsPrintHandler)
  331. {
  332.     CBehaviorIterator iter(this);
  333.  
  334.     for (TBehavior* aBehavior = iter.FirstBehavior(); iter.More(); aBehavior = iter.NextBehavior())
  335.         if (aBehavior->IsMemberClass(GetClassIDFromName("TPrintMenuBehavior")) &&
  336.                         ((TPrintMenuBehavior*)aBehavior)->fPrintHandler == itsPrintHandler)
  337.         {
  338.             this->RemoveBehavior(aBehavior);
  339.             aBehavior->Free();
  340.             break;
  341.         }
  342. }
  343.  
  344. //--------------------------------------------------------------------------------------------------
  345. #pragma segment MARes
  346. pascal void TDocument::Changed(ChangeID theChange,
  347.                                TObject* changedBy)// override 
  348. {
  349.     switch (theChange)
  350.     {
  351.         case cUndo:
  352.             --fChangeCount;
  353.             break;
  354.         default:
  355.             // protect from rollover (it goes negative). If your document has
  356.             // this many changes (over 2 billion you are truly sick!
  357.             this->SetChangeCount(Max(this->GetChangeCount() + 1, 1));
  358.             break;
  359.     }
  360.     inherited::Changed(theChange, changedBy);    // Notify dependents 
  361. }
  362.  
  363. //--------------------------------------------------------------------------------------------------
  364. #pragma segment MAClose
  365.  
  366. short TDocument::OpenWindowCount(void)
  367. {
  368.     short openDocWindows = 0;
  369.     CWindowIterator iter(this);
  370.  
  371.     // See how many open windows this document has 
  372.     for (TWindow* aWindow = iter.FirstWindow(); iter.More(); aWindow = iter.NextWindow())
  373.         if (aWindow->IsShown())
  374.             ++openDocWindows;
  375.     return openDocWindows;
  376. }
  377.  
  378. //--------------------------------------------------------------------------------------------------
  379. #pragma segment MAClose
  380.  
  381. pascal void TDocument::CloseView(TView* aView)
  382. {
  383.     if (aView && (aView->fDocument == this))                // free window 
  384.     {
  385.         // !!! Yuch!, of course we should be able to ASK any view if it would like to close
  386.         // its associated document and maybe even what doc it would like to close.
  387.         // Some other time… 
  388.         if (aView->IsMemberClass(GetClassIDFromName("TWindow")) && ((TWindow *)aView)->fClosesDocument || (this->OpenWindowCount() <= 1))
  389.             this->Close();                        // The view will be closed and freed as a side effect                                    
  390.  
  391.         else
  392.             aView->Close();
  393.     }
  394. }
  395.  
  396. //--------------------------------------------------------------------------------------------------
  397. #pragma segment MAClose
  398.  
  399. pascal void TDocument::Close(void)
  400. {
  401.     TCommand * lastCommand;
  402.     short poseResult;
  403.     long changeCount;
  404.  
  405. #if qDebug
  406.     if (gClipboardMgr->fClipWindow->fDocument == this)
  407.         ProgramBreak("Attempt to close clipboard document");
  408. #endif
  409.  
  410.     changeCount = this->GetChangeCount();
  411.     if (changeCount)
  412.     {
  413.         poseResult = this->PoseSaveDialog();
  414.         if (poseResult == cancel)
  415.             Failure(noErr, msgCancelled);
  416.     }
  417.  
  418.     lastCommand = this->GetLastCommand();
  419.     if (lastCommand && (lastCommand->fChangedObject == this))
  420.         this->CommitLastCommand();
  421.  
  422.     if (changeCount)
  423.     {
  424.         if (poseResult == kYesButton)
  425.             this->SaveDocument(cClose);                // Will fail if unable to save 
  426.         else if (poseResult == kNoButton)
  427.             this->Abandon();
  428.     }
  429.  
  430.     // Must never be called for a document related to a view in the Clipboard.
  431.     // Why is this???
  432.     CWindowIterator iter(this);
  433.  
  434.     for (TWindow* aWindow = iter.FirstWindow(); iter.More(); aWindow = iter.NextWindow())
  435.         aWindow->Close();
  436.  
  437.     this->Free();
  438. }
  439.  
  440. //--------------------------------------------------------------------------------------------------
  441. #pragma segment MAClose
  442.  
  443. pascal void TDocument::DeleteView(TView* viewToDelete)
  444. {
  445.     if (fViewList)
  446.         fViewList->Delete(viewToDelete);
  447.  
  448.     // Make sure the lists are in synch. ??? should we only have one list now (post 2.0)
  449.     if (fWindowList)
  450.         fWindowList->Delete(viewToDelete);
  451. }
  452.  
  453. //--------------------------------------------------------------------------------------------------
  454. #pragma segment MAClose
  455.  
  456. pascal void TDocument::DeleteWindow(TWindow* windowToDelete)
  457. {
  458.     if (fWindowList)
  459.         fWindowList->Delete(windowToDelete);
  460.  
  461.     // Make sure the lists are in synch. ??? should we only have one list now (post 2.0)
  462.     if (fViewList)
  463.         fViewList->Delete(windowToDelete);
  464. }
  465.  
  466. //--------------------------------------------------------------------------------------------------
  467. #pragma segment MAOpen
  468.  
  469. // Called for 'New' && 'Revert' [to blank] commands && for default open tool icon
  470. pascal void TDocument::DoInitialState(void)
  471. {
  472. }
  473.  
  474. //--------------------------------------------------------------------------------------------------
  475. #pragma segment MAOpen
  476.  
  477. pascal void TDocument::DoMakeViews(Boolean forPrinting)
  478.  
  479. //     E X A M P L E
  480. //    {
  481. //        TYOURView*    aYOURView;
  482. //        aYOURView = new TYourView;
  483. //        aYOURView->IYOURView(this, YOURExtentRect);
  484. //        return aYOURView;
  485. //    }
  486.  
  487. {
  488.     if (qTemplateViews)
  489.     {
  490.         TView * aView = NULL;
  491.  
  492.         if (forPrinting)                        // Don't need window when Finder printing. 
  493.             aView = gViewServer->DoCreateViews(this, NULL, kDefaultViewID, gZeroVPt);
  494.         else
  495.             aView = gViewServer->NewTemplateWindow(kDefaultWindowID, this);
  496.  
  497.         // Install a copy of gPrintHandler into the view.  gPrintHandler will be a real printhandler
  498.         // if UPrinting has been initialized otherwise it is a null print handler.
  499.         aView = aView->FindSubView(kIDDefaultView);
  500.         TPrintHandler* aPrintHandler = (TPrintHandler *)gPrintHandler->Clone();
  501.  
  502.         aPrintHandler->fView = aView;
  503.         aPrintHandler->SetDefaultPrintInfo();
  504.         this->AttachPrintHandler(aPrintHandler);
  505.         if (aView)
  506.             aView->AttachPrintHandler(aPrintHandler);
  507.     }
  508. }
  509.  
  510. //--------------------------------------------------------------------------------------------------
  511. #pragma segment MADocumentRes
  512.  
  513. pascal void TDocument::DoMakeWindows(void)
  514. {
  515. }
  516.  
  517. //--------------------------------------------------------------------------------------------------
  518. #pragma segment MASelCommand
  519.  
  520. pascal void TDocument::DoMenuCommand(CmdNumber aCmdNumber)
  521. {
  522.     TSaveDocCommand * aSaveDocCommand;
  523.     TRevertDocCommand * aRevertDocCommand;
  524.     Boolean oldObjectPerm;
  525.  
  526.     /* ==================================================================================
  527.       Some commands will be posted to perform actions that must _ALWAYS_ be available.
  528.       The allocation cannot be allowed to fail.  So we do a temp allocation which by
  529.       definition cannot be allowed to fail.  This strategy is used wherever we want to use
  530.       command objects but don't want to leave the user twisting in the breeze.
  531.       NOTE: Don't forget to allow for this memory in your mem! resource if you copy this
  532.       style in your own code.
  533.       ================================================================================== */
  534.  
  535.     switch (aCmdNumber)
  536.     {
  537.         case cSave:
  538.         case cSaveAs:
  539.         case cSaveCopy:
  540.             oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  541.             aSaveDocCommand = new TSaveDocCommand;
  542.             AllocateObjectsFromPerm(oldObjectPerm);
  543.  
  544.             aSaveDocCommand->ISaveDocCommand(aCmdNumber, this);
  545.             this->PostCommand(aSaveDocCommand);
  546.             break;
  547.  
  548.         case cRevert:
  549.             oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  550.             aRevertDocCommand = new TRevertDocCommand;
  551.             AllocateObjectsFromPerm(oldObjectPerm);
  552.  
  553.             aRevertDocCommand->IRevertDocCommand(aCmdNumber, this);
  554.             this->PostCommand(aRevertDocCommand);
  555.             break;
  556.  
  557.         default:
  558.             inherited::DoMenuCommand(aCmdNumber);
  559.             break;
  560.     }
  561. }
  562.  
  563. //--------------------------------------------------------------------------------------------------
  564. #pragma segment MADocumentRes
  565.  
  566. pascal void TDocument::DoSetupMenus(void)
  567. {
  568.     inherited::DoSetupMenus();
  569.  
  570.     Enable(cSaveAs, TRUE);
  571.     Enable(cSaveCopy, TRUE);
  572.     if (this->GetChangeCount())
  573.     {
  574.         Enable(cSave, TRUE);
  575.         Enable(cRevert, TRUE);
  576.     }
  577. }
  578.  
  579. //--------------------------------------------------------------------------------------------------
  580. #pragma segment MADocumentRes
  581.  
  582. pascal void TDocument::ForAllViewsDo(pascal void(* DoToView)(TView* aView,
  583.                                     void* staticLink), void* staticLink)
  584. {
  585.     CObjectIterator iter(fViewList);
  586.     
  587.     for (TView* aView = (TView*)iter.FirstObject(); iter.More(); aView = (TView*)iter.NextObject())
  588.         DoToView(aView, staticLink);
  589. }
  590.  
  591. //--------------------------------------------------------------------------------------------------
  592. #pragma segment MADocumentRes
  593.  
  594. pascal void TDocument::ForAllWindowsDo(DoToWindType DoToWind,
  595.                                        void* staticLink)
  596. {
  597.     CWindowIterator iter(this);
  598.     
  599.     for (TWindow* aWindow = iter.FirstWindow(); iter.More(); aWindow = iter.NextWindow())
  600.         DoToWind(aWindow, staticLink);
  601. }
  602.  
  603. //--------------------------------------------------------------------------------------------------
  604. #pragma segment MADocumentRes
  605.  
  606. pascal void TDocument::FreeData(void)
  607. {
  608. }
  609.  
  610. //--------------------------------------------------------------------------------------------------
  611. #pragma segment MAClipboard
  612.  
  613. pascal void TDocument::FreeFromClipboard(void)
  614. {
  615.     this->DeleteWindow(gClipboardMgr->fClipWindow);
  616.  
  617.     this->Free();
  618. }
  619.  
  620. //--------------------------------------------------------------------------------------------------
  621. #pragma segment MADocumentRes
  622.  
  623. pascal long TDocument::GetChangeCount(void)
  624. {
  625.     return fChangeCount;
  626. }
  627.  
  628. //--------------------------------------------------------------------------------------------------
  629. #pragma segment MAInspector
  630.  
  631. pascal void TDocument::GetInspectorName(Str255& inspectorName)// override 
  632. {
  633.     inspectorName = fTitle;
  634. }
  635.  
  636. //--------------------------------------------------------------------------------------------------
  637. #pragma segment MADocumentRes
  638.  
  639. pascal void TDocument::DoWriteData(const OSType /* aScrapType */,
  640.                                     TDesignator* /* aDesignator */,
  641.                                     TStream* /* aStream */)
  642. {
  643.     this->SubClassResponsibility();
  644. }
  645.  
  646. //--------------------------------------------------------------------------------------------------
  647. #pragma segment MADocumentRes
  648.  
  649. pascal void TDocument::DoReadData(const OSType /* aScrapType */,
  650.                                     TDesignator* /* aDesignator */,
  651.                                     TStream* /* aStream */,
  652.                                     long /* count */)
  653. {
  654.     this->SubClassResponsibility();
  655. }
  656.  
  657. //--------------------------------------------------------------------------------------------------
  658. #pragma segment MAViewRes
  659.  
  660. pascal TDesignator* TDocument::GetUserSelection(void)
  661. {
  662.     return fUserSelection;
  663. }
  664.  
  665. //--------------------------------------------------------------------------------------------------
  666. #pragma segment MAViewRes
  667.  
  668. pascal void TDocument::SetUserSelection(TDesignator* newSelection)
  669. {
  670.     fUserSelection = (TDesignator *)FreeIfObject(fUserSelection);
  671.     fUserSelection = newSelection;
  672. }
  673.  
  674. //--------------------------------------------------------------------------------------------------
  675. #pragma segment MAViewRes
  676.  
  677. pascal void TDocument::UserSelectionChanged(void)
  678. {
  679. }
  680.  
  681. //--------------------------------------------------------------------------------------------------
  682. #pragma segment MADocumentNonRes
  683.  
  684. pascal void TDocument::RevealSelection(TDesignator*)
  685. {
  686.     // Default behavior: select the first window of the application.
  687.     // Call inherited::RevealSelection() to get this default behavior if you need it.
  688.     
  689.     if (fWindowList)
  690.     {
  691.         TWindow * window = (TWindow *)fWindowList->First();//??? this seems funky 
  692.         window->Select();
  693.     }
  694. }
  695.  
  696. //--------------------------------------------------------------------------------------------------
  697. #pragma segment MAOpen
  698.  
  699. pascal void TDocument::OpenAgain(CmdNumber,
  700.                                  TDocument*)
  701. {
  702.     TWindow * window;
  703.     Str255 name;
  704.  
  705.     name = fTitle;                                // because ParamText allocates memory 
  706.     ParamText(name, "", "", "");
  707.  
  708.     if (fReopenAlert)
  709.         StdAlert(phReopenDoc);                    //!!! This should be programatically defeatable
  710.  
  711.     if (fWindowList)
  712.     {
  713.         window = (TWindow *)fWindowList->First();//??? this seems funky 
  714.         window->Select();
  715.     }
  716. }
  717.  
  718. //--------------------------------------------------------------------------------------------------
  719. #pragma segment MAClose
  720.  
  721. pascal short TDocument::PoseSaveDialog(void)
  722. {
  723.     short idx;
  724.     Str255 name;
  725.     Str255 reason;
  726.     Str255 apName;
  727.     short apRefNum;
  728.     Handle apParam;
  729.  
  730.     if (this->GetChangeCount())
  731.     {
  732.         if (gApplication->fAppDone)
  733.             idx = bzQuitting;
  734.         else
  735.             idx = bzClosing;
  736.  
  737.         GetIndString(reason, kIDBuzzString, idx);
  738.         name = fTitle;                            // ParamText can compact heap 
  739.         GetAppParms(apName, apRefNum, apParam);    // Get the application name 
  740.         ParamText(name, reason, apName, "");
  741.         return MacAppAlert(phSaveChanges, NULL);//!!! This should be programatically
  742.     }
  743.     else
  744.         return kNoButton;
  745. }
  746.  
  747. //--------------------------------------------------------------------------------------------------
  748. #pragma segment MAReadFile
  749.  
  750. pascal void TDocument::ReadDocument(Boolean)
  751. {
  752.     this->SubClassResponsibility();
  753. }
  754.  
  755. //--------------------------------------------------------------------------------------------------
  756. #pragma segment MAReadFile
  757.  
  758. pascal void TDocument::RevertDocument(void)
  759. {
  760.     this->SubClassResponsibility();
  761. }
  762.  
  763.  
  764. //--------------------------------------------------------------------------------------------------
  765. #pragma segment MAClose
  766.  
  767. pascal void TDocument::Abandon(void)
  768. {
  769.     // If your document needs to do some cleanup when its being abandoned then
  770.     // put some code in an override of this method
  771. }
  772.  
  773. //--------------------------------------------------------------------------------------------------
  774. #pragma segment MAWriteFile
  775.  
  776. pascal void TDocument::SaveDocument(CmdNumber)
  777. {
  778.     this->SubClassResponsibility();
  779. }
  780.  
  781. //--------------------------------------------------------------------------------------------------
  782. #pragma segment MAWriteFile
  783.  
  784. pascal void TDocument::SaveAgain(CmdNumber,
  785.                                  TDocument* savingDoc)
  786. {
  787.     // Don't save the file if another one of the same name is already open. 
  788.     if (savingDoc != this)
  789.         Failure(errSaveAgain, 0);
  790. }
  791.  
  792. //--------------------------------------------------------------------------------------------------
  793. #pragma segment MADocumentRes
  794.  
  795. pascal void TDocument::GetTitle(Str255& aTitle)
  796. {
  797.     aTitle = fTitle;
  798. }
  799.  
  800. //--------------------------------------------------------------------------------------------------
  801. #pragma segment MADocumentRes
  802.  
  803. pascal void TDocument::SetTitle(const Str255& aTitle)
  804. {
  805.     CWindowIterator iter(this);
  806.     
  807.     fTitle = aTitle;
  808.     for (TWindow* aWindow = iter.FirstWindow(); iter.More(); aWindow = iter.NextWindow())
  809.         aWindow->SetTitleForDoc(aTitle);
  810. }
  811.  
  812. //--------------------------------------------------------------------------------------------------
  813. #pragma segment MADocumentRes
  814.  
  815. pascal void TDocument::SetChangeCount(long newChangeCount)
  816.  
  817. // (??? should we add this as a default action with a TView.DocumentChanged method?)
  818. // You can notify your views that the document changed something like this:
  819. // pascal void NotifyChange(TView* aView)
  820. //    {
  821. //        if (aView && aView->IsMemberClass(GetClassIDFromName("TMyClass)))
  822. //            ((TMyView)aView)->DocumentChanged(newChangeCount);
  823. //    }
  824. {
  825.     fChangeCount = newChangeCount;
  826.     // this->ForAllViewsDo(NotifyChange); 
  827. }
  828.  
  829. //--------------------------------------------------------------------------------------------------
  830. #pragma segment MAReadFile
  831.  
  832. pascal void TDocument::ShowReverted(void)
  833. {
  834.     CObjectIterator iter(fViewList);
  835.     
  836.     for (TView* aView = (TView*)iter.FirstObject(); iter.More(); aView = (TView*)iter.NextObject())
  837.         aView->ShowReverted();
  838. }
  839.  
  840. //--------------------------------------------------------------------------------------------------
  841. #pragma segment MAOpen
  842.  
  843. pascal Boolean ShowAWindow(TWindow* aWindow, void*)
  844. {
  845.     if (aWindow->fOpenInitially)
  846.         aWindow->Open();
  847.     return FALSE;
  848. }
  849.  
  850. pascal void TDocument::ShowWindows(void)
  851. {
  852.     // Make the windows open from back to front 
  853.     if (fWindowList)
  854.         fWindowList->LastThat((TestObjectType)ShowAWindow, this);
  855. }
  856.  
  857. //--------------------------------------------------------------------------------------------------
  858. #pragma segment MAOpen
  859.  
  860. pascal void TDocument::UntitledName(Str255& noName)
  861. {
  862.     short preInsert;
  863.     short constChars;
  864.     Str255 num;
  865.  
  866.     GetIndString(noName, kIDBuzzString, bzUntitled);
  867.     if (ParseTitleTemplate(noName, preInsert, constChars))
  868.     {
  869.         NumToString(gNumUntitled, num);
  870.  
  871.         if (SubstituteInTitle(noName, num, preInsert, constChars))
  872.             ++gNumUntitled;
  873.     }
  874. }
  875.  
  876. //--------------------------------------------------------------------------------------------------
  877. #pragma segment MAFields
  878.  
  879. pascal void TDocument::Fields(TObject* obj)
  880. {
  881.     obj->DoToField("TDocument", (Ptr)NULL, bClass);
  882.     obj->DoToField("fTitle", (Ptr) & fTitle, bString);
  883.     obj->DoToField("fWindowList", (Ptr) & fWindowList, bObject);
  884.     obj->DoToField("fViewList", (Ptr) & fViewList, bObject);
  885.     obj->DoToField("fChangeCount", (Ptr) & fChangeCount, bLongInt);
  886.     obj->DoToField("fSavePrintInfo", (Ptr) & fSavePrintInfo, bBoolean);
  887.     obj->DoToField("fSharePrintInfo", (Ptr) & fSharePrintInfo, bBoolean);
  888.     obj->DoToField("fPrintInfo", (Ptr) & fPrintInfo, bHandle);
  889.     obj->DoToField("fReopenAlert", (Ptr) & fReopenAlert, bBoolean);
  890.     obj->DoToField("fCommitOnSave", (Ptr) & fCommitOnSave, bBoolean);
  891.  
  892.     inherited::Fields(obj);
  893. }
  894.  
  895.  
  896.